import os
import time

from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QDialog, QListView, QInputDialog, QLineEdit
from uiFiles import ui_advancedSetting
from gtyConfig import language
import uiTools
from gtyTools import gtyTypes
import json


class AdvancedSetting(QDialog, ui_advancedSetting.Ui_advancedsetting):
    def __init__(self, mainPage, eventQ, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        uiTools.centerAndSetIcon(self)

        self.eventQ = eventQ
        self.mainPage = mainPage
        self.languageList = ['english', 'chinese', 'korean', 'traditionalChinese']
        self.serverLocationJson = 'platform/configFiles/serverlocation.json'
        with open(self.serverLocationJson, 'r') as f:
            self.serverlocationList = json.load(f)
        self.HardwareTypeList = ['F800', 'A400', 'F2000']
        # 开关量的选项
        self.enableoptionsList = ['logEnable', 'beepEnable', 'onlyOneLogFile', 'autoDeleteLogFile', 'enable',
                                  'enRespond', 'ShowFilteredTags']
        # 定制的格式选项
        self.formatnumList = ['', 'format1', 'format2', 'format3', 'format4', 'format5', 'format6', 'format7',
                              'format8']
        self.enableList = ['0', '1']
        self.warningoptionsList = ['hardwareType']
        self.warning_password = os.environ.get("platform4_linuxPassword")
        self.configHandlers = gtyTypes.ConfigHandlers()

        self.initUI()
        self.initEvents()
        self.getOptions()
        self.showValue()

        self.setGeometry(-200, -200, self.width(), self.height())
        # 防止修改后点击重启过慢自动断电，发送进入debug模式但不修改配置文件
        self.sendEvent('UART', 'uart_sendReleaseMode', ['debug'])
        self.debugMode = self.configHandlers.state.read('machine', 'releaseMode') == 'debug'
        if not self.debugMode:
            self.btnSetDefault.hide()

    def initUI(self):
        self.setWindowTitle('Advanced Setting')
        self.label.setText(language.advancedSetting_info)
        self.label_2.setText(language.advancedSetting_configItem)
        self.label_3.setText(language.advancedSetting_value)
        self.btnSet.setText(language.advancedSetting_set)
        self.btnBack.setText(language.advancedSetting_back)
        self.btnSetDefault.setText(language.advancedSetting_setDefault)
        self.comboBoxSection.addItems(self.configHandlers.systemMachine.config.sections())
        self.comboBoxSection.setStyleSheet("QAbstractItemView::item {height: 45px;}")
        self.comboBoxSection.setView(QListView())

    def initEvents(self):
        self.btnBack.clicked.connect(self.closewindow)
        self.comboBoxSection.currentIndexChanged.connect(self.getOptions)
        self.comboBoxOption.currentIndexChanged.connect(self.showValue)
        self.comboBox_value.currentIndexChanged.connect(self.onComboBoxValueChange)
        self.btnSet.clicked.connect(self.setValue)
        self.btnSetDefault.clicked.connect(self.setDefaultValue)

    def updateComboBoxValue(self, items):
        self.comboBox_value.clear()
        self.comboBox_value.addItems(items)

    def getOptions(self):
        section = self.comboBoxSection.currentText()
        # 阻止 comboBoxOption 发射信号，防止 showValue触发时option还未更新
        self.comboBoxOption.blockSignals(True)
        self.comboBoxOption.clear()
        options = self.configHandlers.systemMachine.config.options(section)
        # 移除高危选项
        # if not self.debugMode:
        #     for option in options:
        #         if option in self.warningoptionsList:
        #             options.remove(option)
        self.comboBoxOption.addItems(options)
        self.comboBoxOption.setView(QListView())
        # 选择第一个选项，确保 showValue 获取到正确的 option
        if options:
            self.comboBoxOption.setCurrentIndex(0)
        # 重新允许信号发射
        self.comboBoxOption.blockSignals(False)
        # 使用 QTimer 确保 showValue 在 comboBoxOption 更新后执行
        QTimer.singleShot(0, self.showValue)

    def showValue(self):
        try:
            section = self.comboBoxSection.currentText()
            option = self.comboBoxOption.currentText()
            value = self.configHandlers.machine.read(section, option)
            use_combo = option in {'displayLanguage', 'serverLocation',
                                   'hardwareType', 'formatnum', *self.enableoptionsList}
            self.comboBox_value.setVisible(use_combo)
            self.lineEdit.setVisible(not use_combo)
            item_map = {
                'displayLanguage': self.languageList,
                'serverLocation': self.serverlocationList,
                'hardwareType': self.HardwareTypeList,
                'formatnum': self.formatnumList,
            }
            items = item_map.get(option, self.enableList if option in self.enableoptionsList else [])
            if items:
                self.updateComboBoxValue(items)
                self.comboBox_value.setCurrentIndex(self.comboBox_value.findText(value))
            else:
                self.lineEdit.setText(value)
        except Exception as e:
            print(e)

    def setValue(self):
        section, option = self.comboBoxSection.currentText(), self.comboBoxOption.currentText()
        value = self.comboBox_value.currentText() if option in ['displayLanguage',
                                                                'serverLocation',
                                                                'hardwareType',
                                                                'formatnum'
                                                                ] + self.enableoptionsList else self.lineEdit.text()
        if option in self.warningoptionsList:
            password, ok = QInputDialog.getText(self, 'Warning',
                                                f'Are you sure to set {option} to {value}?\nplease enter password to confirm.',
                                                QLineEdit.Password)
            if not ok:
                return
            if password != self.warning_password:
                self.label_info.setText('password error!')
                return
        self.configHandlers.machine.write(section, option, value)
        self.label_info.setText('set value ok!')

    def setDefaultValue(self):
        # 重置用户配置文件前保留当前的硬件类型
        hardwareType = self.configHandlers.machine.read('machine', 'hardwareType')
        self.configHandlers.machine.resetUserConfigFile()
        self.configHandlers.machine.write('machine', 'hardwareType', hardwareType)
        self.label_info.setText('config value set to default!')

    def sendEvent(self, task, eventName, eventData=None):
        try:
            if task.upper() in self.eventQ:
                self.eventQ[task.upper()].put([eventName, eventData or []])
        except Exception as e:
            print(e)

    def onComboBoxValueChange(self):
        if self.comboBoxOption.currentText() == 'serverLocation':
            current_value = self.comboBox_value.currentText()
            if current_value == 'add new server location...':
                self.addNewServerLocation()

    def addNewServerLocation(self):
        dialog = QInputDialog(self)
        dialog.setWindowTitle('Add Server Location')
        dialog.setLabelText('Enter new server location URL:')
        dialog.resize(400, 150)
        ok = dialog.exec_() == QInputDialog.Accepted
        new_location = dialog.textValue()
        if ok and new_location:
            if new_location in self.serverlocationList:
                self.label_info.setText('This server location already exists.')
            else:
                # 插入到 add new... 之前
                self.serverlocationList.insert(len(self.serverlocationList) - 1, new_location)
                # 更新 ComboBox 显示
                self.updateComboBoxValue(self.serverlocationList)
                self.comboBox_value.setCurrentText(new_location)
                # 写入到 JSON 文件中
                try:
                    with open(self.serverLocationJson, 'w') as f:
                        json.dump(self.serverlocationList, f, indent=4)
                except Exception as e:
                    self.label_info.setText(f'Failed to save serverlocation.json: {e}')
        else:
            # 若用户取消输入，则恢复到原有值
            self.showValue()

    def closewindow(self):
        # 如果进入页面之前就是debug模式，则不发送恢复release模式的事件
        if not self.debugMode:
            self.sendEvent('UART', 'uart_sendReleaseMode', ['release'])
        self.close()
